From a925f0891d2ee762a93cc20c1076e04072cf1dcb Mon Sep 17 00:00:00 2001 From: robertl Date: Fri, 12 Nov 2004 05:59:43 +0000 Subject: [PATCH] Another round of coastal explorer changes from Justin. Regenerate refs. Tweak portable times. --- gpsbabel/coastexp.c | 168 ++++++++++++++++++++----------- gpsbabel/defs.h | 4 + gpsbabel/reference/coastexp.ref2 | 80 +++++++-------- gpsbabel/reference/coastexp.ref4 | 78 +++++++------- gpsbabel/testo | 6 -- gpsbabel/vecs.c | 2 +- gpsbabel/xmlgeneric.c | 22 +++- 7 files changed, 213 insertions(+), 147 deletions(-) diff --git a/gpsbabel/coastexp.c b/gpsbabel/coastexp.c index aa8aaf0a4..1e1b4e10e 100755 --- a/gpsbabel/coastexp.c +++ b/gpsbabel/coastexp.c @@ -31,8 +31,9 @@ FILE *ofd; #define MYNAME "coastexp" #define MY_CBUF 4096 -#define MY_TBUF 64 #define MY_UBUF 128 +#define MY_TBUF 64 +#define MY_XBUF 128 #if NO_EXPAT void @@ -47,7 +48,6 @@ ce_read(void) } #else -static void *mkshort_handle; // short-name handle static char *element; // Current element being parsed static char *cdatastr; // Current XML character data being built up (until a ) @@ -76,33 +76,34 @@ static queue ce_mark_head; // List of stand-alone marks currently found static ce_mark *currentMark = NULL; // Current mark being processed static char *time_buffer = NULL; // Time buffer for processing times static char *uuid_buffer = NULL; // UUID buffer for processing uuid's +static char *xml_buffer = NULL; // XML buffer for processing XML strings static int inRoute = 0; // Are we processing a route? static int inMark = 0; // Are we processing a mark? /* Add a route to the list of routes */ static void -add_route(ce_route *route) +ce_add_route(ce_route *route) { ENQUEUE_TAIL(&ce_route_head, &route->Q); } /* Add a mark to the list of stand-alone marks */ static void -add_mark(ce_mark *mark) +ce_add_mark(ce_mark *mark) { ENQUEUE_TAIL(&ce_mark_head, &mark->Q); } /* Add a mark to the specified route */ static void -add_mark_to_route(ce_route *route, ce_mark *mark) +ce_add_mark_to_route(ce_route *route, ce_mark *mark) { ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); } /* Free a mark */ static void -free_mark(ce_mark *mark) +ce_free_mark(ce_mark *mark) { xfree(mark->id); if (mark->created) @@ -112,12 +113,12 @@ free_mark(ce_mark *mark) /* Free a route */ static void -free_route(ce_route *route) +ce_free_route(ce_route *route) { queue *elem, *tmp; QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { ce_mark *mark = (ce_mark *) elem; - free_mark(mark); + ce_free_mark(mark); } xfree(route->id); xfree(route); @@ -137,9 +138,10 @@ ce_start(void *data, const char *el, const char **attr) // Create a CE route object and add it to the list of routes currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); currentRoute->id=xstrdup(ap[1]); + if (doing_rtes) currentRoute->r = route_head_alloc(); QUEUE_INIT(¤tRoute->ce_mark_head); - add_route(currentRoute); + ce_add_route(currentRoute); } } } else if (0 == strcmp(el, "Mark")) { @@ -147,7 +149,7 @@ ce_start(void *data, const char *el, const char **attr) currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); currentMark->wp = NULL; currentMark->used = 0; - add_mark(currentMark); + ce_add_mark(currentMark); for (ap = attr; *ap; ap+=2) { if (0 == strcmp(ap[0], "id")) { // Create a CE mark object and add it to the list of stand-alone marks @@ -199,7 +201,7 @@ ce_cdata(void *dta, const XML_Char *s, int len) mark->id = xstrdup(s); mark->created = NULL; mark->wp = NULL; - add_mark_to_route(currentRoute, mark); + ce_add_mark_to_route(currentRoute, mark); } } else if (0 == strcmp(element, "Position")) { if (inMark) { @@ -264,8 +266,10 @@ ce_cdata(void *dta, const XML_Char *s, int len) currentMark->wp->creation_time = mktime(&t); } } - else if (inRoute) + else if (inRoute) { + if (doing_rtes) currentRoute->r->rte_name = xstrdup(s); + } } else if (0 == strcmp(element, "Description")) { // Descriptions we care about may be either for routes or marks char *desc = xstrdup(s); @@ -325,7 +329,7 @@ ce_read(void) /* Fix waypoints in route marks from the standalone marks */ void -ce_fix_waypoints(void) +ce_fix_route_mark_waypoints(void) { queue *elem, *tmp; QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { @@ -365,7 +369,7 @@ ce_check_route_names(void) /* Remove marks used in routes */ void -ce_remove_unused_marks(void) +ce_remove_used_marks(void) { queue *elem, *tmp; QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { @@ -375,7 +379,7 @@ ce_remove_unused_marks(void) dequeue(elem); if (mark->wp) waypt_free(mark->wp); - free_mark(mark); + ce_free_mark(mark); } } } @@ -412,16 +416,27 @@ ce_print_results(void) void ce_rd_deinit(void) { + /* If doing routes, we create GPSBabel route structures and waypoint structures for + any standalone waypoints. + If doing waypoints, we create only waypoint structures for both route waypoints and + standalone waypoints. + */ queue *elem, *tmp; - ce_fix_waypoints(); + if (doing_rtes) { + ce_fix_route_mark_waypoints(); ce_check_route_names(); - ce_remove_unused_marks(); - // ce_print_results(); + ce_remove_used_marks(); + } + + // Log results + if (global_opts.debug_level > 1) + ce_print_results(); // Add routes to GPSBabel QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { ce_route *route = (ce_route *) elem; + if (doing_rtes) { queue *elem2, *tmp2; route_add_head(route->r); QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { @@ -431,14 +446,15 @@ ce_rd_deinit(void) else printf("Undefined mark: %s\n", mark->id); } - free_route(route); + } + ce_free_route(route); } // Add (unused) marks to GPSBabel QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { ce_mark *mark = (ce_mark *) elem; waypt_add(mark->wp); - free_mark(mark); + ce_free_mark(mark); } fclose(fd); @@ -446,13 +462,16 @@ ce_rd_deinit(void) xfree(cdatastr); } +/* Setup for writing */ void ce_wr_init(const char *fname) { - mkshort_handle = mkshort_new_handle(); QUEUE_INIT(&ce_mark_head); + + // Alloocate all buffers used for writing time_buffer = xcalloc(MY_TBUF,1); uuid_buffer = xcalloc(MY_UBUF,1); + xml_buffer = xcalloc(MY_XBUF, 1); ofd = xfopen(fname, "w", MYNAME); } @@ -461,25 +480,29 @@ void ce_wr_deinit(void) { fclose(ofd); - mkshort_del_handle(mkshort_handle); + + // Free the buffers used for writing xfree(time_buffer); xfree(uuid_buffer); + xfree(xml_buffer); } +/* Generate a CE-style creation time based on supplied time */ static char * ce_gen_creation_time(time_t tm) { - struct tm *t = localtime(&tm); - sprintf(time_buffer, "%04d%02d%02dT%02d%02d%02dZ", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + xml_fill_in_time(time_buffer, tm, XML_SHORT_TIME); return time_buffer; } +/* Generate a CE-style creation time based on current time */ static char * ce_gen_current_time(void) { return ce_gen_creation_time(current_time()); } +/* Generate a UUID (has same format as Microsoft registry GUIDs */ static char * ce_gen_uuid(void) { @@ -491,13 +514,18 @@ ce_gen_uuid(void) return uuid_buffer; } +/* Generate route header XML */ static void ce_route_hdr(const route_head *rte) { - fprintf(ofd, "\t\n", ce_gen_current_time(), ce_gen_uuid()); - fprintf(ofd, "\t\t\n"); + if (doing_rtes) { + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); + write_xml_entity_begin0(ofd, "\t\t", "Marks"); + } } +/* Generate route body XML */ static void ce_route_disp(const waypoint *waypointp) { @@ -508,34 +536,29 @@ ce_route_disp(const waypoint *waypointp) currentMark->id = id; currentMark->wp = (waypoint *) waypointp; ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); - fprintf(ofd, "\t\t\t%s\n", id); + fprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! } +/* Generate route trailer XML */ static void ce_route_tlr(const route_head *rte) { - fprintf(ofd, "\t\t\n"); - if (rte->rte_name) - fprintf(ofd, "\t\t%s\n", rte->rte_name); - fprintf(ofd, "\t\n"); -} - -static void -ce_waypt_pr(const waypoint *waypointp) -{ + if (doing_rtes) { + write_xml_entity_end(ofd, "\t\t", "Marks"); + write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); + write_xml_entity_end(ofd, "\t", "Route"); + } } +/* Generate waypoint body XML */ static void -ce_mark_pr(void) +ce_waypt_pr(const waypoint *wp) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - double latitude = mark->wp->latitude; + double latitude = wp->latitude; char NorS = 'N'; char EorW = 'E'; - double longitude = mark->wp->longitude; - fprintf(ofd, "\t\n", ce_gen_creation_time(mark->wp->creation_time), mark->id); + double longitude = wp->longitude; + if (latitude < 0) { latitude = -latitude; NorS = 'S'; @@ -544,29 +567,60 @@ ce_mark_pr(void) longitude = -longitude; EorW = 'W'; } - fprintf(ofd, "\t\t%3.6f %c %3.6f %c\n", latitude, NorS, longitude, EorW); - if (mark->wp->shortname) - fprintf(ofd, "\t\t%s\n", mark->wp->shortname); - fprintf(ofd, "\t\n"); - free_mark(mark); + sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); + write_xml_entity(ofd, "\t\t", "Position", xml_buffer); + write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); +} + +/* Generate a standalone mark XML */ +static void +ce_standalone_mark_pr(const waypoint *wp) +{ + write_xml_entity_begin2(ofd, "\t", "Mark", + "created", ce_gen_current_time(), + "id", ce_gen_uuid()); + ce_waypt_pr(wp); + write_xml_entity_end(ofd, "\t", "Mark"); +} + +/* Generate all route marks */ +static void +ce_marks_pr(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + write_xml_entity_begin2(ofd, "\t", "Mark", + "created", ce_gen_creation_time(mark->wp->creation_time), + "id", mark->id); + ce_waypt_pr(mark->wp); + write_xml_entity_end(ofd, "\t", "Mark"); + ce_free_mark(mark); } } +/* Write all routes and marks */ void ce_write(void) { - setshort_whitespace_ok(mkshort_handle, 0); - setshort_length(mkshort_handle, 32); - - fprintf(ofd, "\n"); - fprintf(ofd, "Navigation Objects\n"); + /* If doing routes, we write out the routes and all the standalone waypoints. + If doing waypoints, we write out the route waypoints (without the routes) and + the standalone waypoints. + */ + time_t now = 0; + int short_length; + now = current_time(); + + write_xml_header(ofd); + write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", + ce_gen_current_time()); + write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); - ce_mark_pr(); - waypt_disp_all(ce_waypt_pr); + ce_marks_pr(); + waypt_disp_all(ce_standalone_mark_pr); - fprintf(ofd, "\n"); + write_xml_entity_end(ofd, "", "NavObjectCollection"); } ff_vecs_t coastexp_vecs = { diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 7e8d0ad1f..32f895f15 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -86,6 +86,10 @@ typedef struct { extern global_options global_opts; extern const char gpsbabel_version[]; +/* Short or Long XML Times */ +#define XML_SHORT_TIME 1 +#define XML_LONG_TIME 2 + /* * Extended data if waypoint happens to represent a geocache. This is * totally voluntary data... diff --git a/gpsbabel/reference/coastexp.ref2 b/gpsbabel/reference/coastexp.ref2 index ea914c8f3..2f73b4d97 100644 --- a/gpsbabel/reference/coastexp.ref2 +++ b/gpsbabel/reference/coastexp.ref2 @@ -1,7 +1,7 @@ - + Navigation Objects - + {10111213-1415-1617-1819-1a1b1c1d1e1f} {20212223-2425-2627-2829-2a2b2c2d2e2f} @@ -16,155 +16,155 @@ Into The Bay - + 37.763290 N 122.282580 W SFBALBAY - + 37.751613 N 122.339028 W SFBAY001 - + 37.817420 N 122.394305 W SFBAY002 - + 37.819339 N 122.478302 W SFGGBRDG - + 37.773033 N 122.605838 W SFCHNL01 - + 37.518860 N 122.529914 W HMCOLREF - + 37.482348 N 122.507704 W HMPILL01 - + 37.475062 N 122.488531 W HMPILLPT - + 37.476448 N 122.475800 W HMPILL02 - + 37.495102 N 122.483927 W HMPILL03 - + 37.229349 N 122.441589 W PESCDR01 - + 37.183397 N 122.411904 W PIGEON01 - + 37.090736 N 122.348775 W ANONUV01 - + 36.929502 N 122.113725 W SCRUZ01 - + 36.934235 N 122.022130 W SCRUZ02 - + 36.960666 N 122.024734 W SCRUZENT - + 36.581344 N 121.995411 W CYPRSSPT - + 36.301110 N 121.919097 W PTSUR - + 36.238177 N 121.855209 W COOPERPT - + 36.225175 N 121.801314 W PFEIFENT - + 36.230449 N 121.797444 W PFEIFANC - + 35.879801 N 121.498947 W SANMRT01 - + 35.652801 N 121.308485 W PDRSBLNC - + 35.623297 N 121.185920 W SNSMNENT - + 35.640478 N 121.183772 W SNSMNANC - + 35.572353 N 121.152797 W CAMBRIA - + 35.449214 N 121.020825 W PTESTERO - + 35.216602 N 120.928391 W PTBUCHON - + 34.883361 N 120.684631 W PTSAL01 - + 34.884641 N 120.652026 W PTSALENT - + 34.896555 N 120.649124 W PTSALANC - + 34.758180 N 120.642516 W PURSMAPT - + 34.572579 N 120.663636 W PTARGLLO - + 34.113844 N 120.492630 W SANMGL01 - + 34.029483 N 120.471409 W SANMGL02 - + 34.019184 N 120.444197 W SANMGL03 - + 34.023478 N 120.438209 W ADCOVENT - + 34.028615 N 120.439696 W ADCOVANC diff --git a/gpsbabel/reference/coastexp.ref4 b/gpsbabel/reference/coastexp.ref4 index 7752443aa..1cbc015dc 100644 --- a/gpsbabel/reference/coastexp.ref4 +++ b/gpsbabel/reference/coastexp.ref4 @@ -1,155 +1,155 @@ - + Navigation Objects - + 37.763290 N 122.282580 W SFBALBAY - + 37.751613 N 122.339028 W SFBAY001 - + 37.817420 N 122.394305 W SFBAY002 - + 37.819339 N 122.478302 W SFGGBRDG - + 37.773033 N 122.605838 W SFCHNL01 - + 37.518860 N 122.529914 W HMCOLREF - + 37.482348 N 122.507704 W HMPILL01 - + 37.476448 N 122.475800 W HMPILL02 - + 37.495102 N 122.483927 W HMPILL03 - + 37.229349 N 122.441589 W PESCDR01 - + 37.183397 N 122.411904 W PIGEON01 - + 37.090736 N 122.348775 W ANONUV01 - + 36.929502 N 122.113725 W SCRUZ01 - + 36.934235 N 122.022130 W SCRUZ02 - + 36.960666 N 122.024734 W SCRUZENT - + 37.475062 N 122.488531 W HMPILLPT - + 36.581344 N 121.995411 W CYPRSSPT - + 36.301110 N 121.919097 W PTSUR - + 36.238177 N 121.855209 W COOPERPT - + 36.225175 N 121.801314 W PFEIFENT - + 36.230449 N 121.797444 W PFEIFANC - + 35.879801 N 121.498947 W SANMRT01 - + 35.652801 N 121.308485 W PDRSBLNC - + 35.623297 N 121.185920 W SNSMNENT - + 35.640478 N 121.183772 W SNSMNANC - + 35.572353 N 121.152797 W CAMBRIA - + 35.449214 N 121.020825 W PTESTERO - + 35.216602 N 120.928391 W PTBUCHON - + 34.883361 N 120.684631 W PTSAL01 - + 34.884641 N 120.652026 W PTSALENT - + 34.896555 N 120.649124 W PTSALANC - + 34.758180 N 120.642516 W PURSMAPT - + 34.572579 N 120.663636 W PTARGLLO - + 34.113844 N 120.492630 W SANMGL01 - + 34.029483 N 120.471409 W SANMGL02 - + 34.019184 N 120.444197 W SANMGL03 - + 34.023478 N 120.438209 W ADCOVENT - + 34.028615 N 120.439696 W ADCOVANC diff --git a/gpsbabel/testo b/gpsbabel/testo index cd772eead..37a35d2de 100755 --- a/gpsbabel/testo +++ b/gpsbabel/testo @@ -401,12 +401,6 @@ ${PNAME} -i navicache -f reference/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wp compare ${TMPDIR}/navi.wpt reference/navicache.ref # -# -# CoastalExplorer.. -${PNAME} -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx -compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref -# - # # CoastalExplorer.. ${PNAME} -r -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 0229ebc3b..81af43c38 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -228,7 +228,7 @@ vecs_t vec_list[] = { { &coastexp_vecs, "coastexp", - "CoastalExplorer.com XML", + "CoastalExplorer XML", NULL }, { /* MRCB */ diff --git a/gpsbabel/xmlgeneric.c b/gpsbabel/xmlgeneric.c index 14e254bbf..35f760603 100644 --- a/gpsbabel/xmlgeneric.c +++ b/gpsbabel/xmlgeneric.c @@ -91,21 +91,35 @@ write_xml_entity_end(FILE *ofd, const char *indent, } void -xml_write_time(FILE *ofd, const time_t timep, char *elname) +xml_fill_in_time(char *time_string, const time_t timep, int long_or_short) { struct tm *tm = gmtime(&timep); + char *format; if (!tm) return; - fprintf(ofd, "<%s>%02d-%02d-%02dT%02d:%02d:%02dZ\n", - elname, + if (long_or_short == XML_LONG_TIME) + format = "%02d-%02d-%02dT%02d:%02d:%02dZ"; + else + format = "%02d%02d%02dT%02d%02d%02dZ"; + sprintf(time_string, format, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec, + tm->tm_sec); +} + +void +xml_write_time(FILE *ofd, const time_t timep, char *elname) +{ + char time_string[64]; + xml_fill_in_time(time_string, timep, XML_LONG_TIME); + fprintf(ofd, "<%s>%s\n", + elname, + time_string, elname ); -- 2.30.2